package archer.application.manager.shiro;

import archer.application.manager.service.system.StaffService;
import archer.framework.protocol.exception.NotLoginedException;
import archer.framework.protocol.result.ExecuteResult;
import archer.framework.utils.ContextUtils;
import archer.framework.utils.ServletUtils;
import archer.framework.utils.ValidateUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 菜单过滤器
 *
 * @author christ
 * @date 2016/6/28
 */
public class MenuFilter extends org.apache.shiro.web.filter.authc.UserFilter {

    private static Logger logger = LoggerFactory.getLogger(MenuFilter.class);

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {

        if (isLoginRequest(request, response)) {

            return true;
        }

        Subject subject = getSubject(request, response);

        if (subject == null || subject.getPrincipal() == null) {

            throw new NotLoginedException();
        }

        String path = getPathWithinApplication(request);

        for (Map each : getMenus(subject)) {

            if (pathsMatch((String) each.get("url"), path)) {
                return true;
            }
        }

        return false;
    }

    protected List<Map> getMenus(Subject subject) {

        List<Map> menus = (List<Map>) subject.getSession().getAttribute("all-menu");

        if (ValidateUtils.isNotEmpty(menus)) {

            return menus;
        }

        ExecuteResult result = ContextUtils.getBean(StaffService.class).findMyMenuList();

        if (result.isSuccess() && ValidateUtils.isNotEmpty(result.getResultData())) {

            menus = (List) result.getResultData();

            subject.getSession(true).setAttribute("all-menu", menus);

            return menus;
        }

        return new ArrayList<>();
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {

        logger.error("MENU ACCESS DENIED>>" + ServletUtils.getRequestURI(request));

        ServletUtils.redirect(request, response, "/error/403");

        return false;
    }
}
